
package org.bridgen.lang.semantics.ast;
import java.util.*;
/* 
 * JastAdd AST declarations for the Bridge Grammar language
 *
 * Emma S\u00f6derberg <emma at cs.lth.se>  
 */
 
 
/* Top node */ 


public class Program extends ASTNode<ASTNode> implements Cloneable {
    public void flushCache() {
        super.flushCache();
    collect_contributors_Grammar_nodeDecls = false;
    collect_contributors_Grammar_ignoreDecls = false;
    collect_contributors_NodeDecl_attrDecls = false;
    }
     @SuppressWarnings({"unchecked", "cast"})  public Program clone() throws CloneNotSupportedException {
        Program node = (Program)super.clone();
        node.in$Circle(false);
        node.is$Final(false);
    return node;
    }
     @SuppressWarnings({"unchecked", "cast"})  public Program copy() {
      try {
          Program node = (Program)clone();
          if(children != null) node.children = (ASTNode[])children.clone();
          return node;
      } catch (CloneNotSupportedException e) {
      }
      System.err.println("Error: Could not clone node of type " + getClass().getName() + "!");
      return null;
    }
     @SuppressWarnings({"unchecked", "cast"})  public Program fullCopy() {
        Program res = (Program)copy();
        for(int i = 0; i < getNumChildNoTransform(); i++) {
          ASTNode node = getChildNoTransform(i);
          if(node != null) node = node.fullCopy();
          res.setChild(node, i);
        }
        return res;
    }
    // Declared in ParserCodeGen.jrag at line 9


	public void generateParserCode(String packageName, String parserName, StringBuffer buf) {
	
		String indent = INDENT;
		
		// Package 		
		if (packageName.trim().length() > 0) {
			buf.append("package " + packageName + ";\n\n");
		} 
		
		// Imports
		buf.append("import org.bripgen.generic.*;\n");
		buf.append("import org.briplib.recovery.*;\n");
		buf.append("import org.briplib.recovery.util.*;\n\n");
	
		// Class signature
		buf.append("public class " + parserName + " extends AbstractBridgeParser {\n\n");
		
		// Method body
		generateMethod_match(indent, buf);
		generateMethod_matchIgnore(indent, buf);
		
		buf.append("}\n"); 
	}

    // Declared in ParserCodeGen.jrag at line 35

	
	// Code generation of method match
	
	public void generateMethod_match(String indent, StringBuffer buf) {
		buf.append(indent + "protected LexicalNode matchNode(char[] content, " +
			"int curPos, int lastMatchPos, LexicalNode previous) {\n");
			
		// Method body
		for (int i = 0; i < getNumGrammar(); i++) {
			Grammar g = getGrammar(i);
			for (Object obj : g.nodeDecls()) {
				NodeDecl decl = (NodeDecl)obj;
				if (!decl.inBaseLibrary())
					decl.generateMethod_match(indent + indent, buf);
			}
		}
				
		// Method end
		buf.append(indent + INDENT + "return null;\n");
		buf.append(indent + "}\n\n");	
	}

    // Declared in ParserCodeGen.jrag at line 82

	
	// Code generation of method matchIgnore
	
	public void generateMethod_matchIgnore(String indent, StringBuffer buf) {
		buf.append(indent + "protected LexicalNode matchIgnore(char[] content, " +
			"int curPos, int lastMatchPos, LexicalNode previous) {\n");  
			
		// Method body
		for (int i = 0; i < getNumGrammar(); i++) {
			Grammar g = getGrammar(i);
			for (Object obj : g.ignoreDecls()) {
				IgnoreDecl decl = (IgnoreDecl)obj;
				decl.generateMethod_matchIgnore(indent + indent, buf);
			}
		}
			
		buf.append(indent + INDENT + "return null;\n");
		buf.append(indent + "}\n\n");
	}

    // Declared in ParserCodeGen.jrag at line 115


	public void generateSGLRParserCode(String packageName, String parserName, StringBuffer buf) {
		String indent = "\t"; 
		
		// Package 		
		if (packageName.trim().length() > 0) {
			buf.append("package " + packageName + ";\n\n");
		} 
		
		// Imports
		buf.append("import org.bripgen.sglr.*;\n");
		buf.append("import org.strategoxt.imp.runtime.parser.StandAloneSGLRI;\n");
		buf.append("import org.briplib.recovery.*;\n");
		buf.append("import org.briplib.recovery.base.SOF;\n");
		buf.append("import org.briplib.recovery.util.*;\n\n");
		
		// Class signature
		buf.append("public class " + parserName + " extends AbstractSGLRBridgeParser {\n\n");

		// Constructor
		buf.append(indent + "public " + parserName + "(StandAloneSGLRI tokenParser) {\n");
		buf.append(indent + indent + "super(tokenParser);\n");
		buf.append(indent + "}\n\n");

		// Class body		
		generateSGLRMethod_match(indent, buf);
		generateSGLRMethod_createWater(indent, buf);
		generateSGLRMethod_mergeNodes(indent, buf);
		
		buf.append("}\n");
	}

    // Declared in ParserCodeGen.jrag at line 148

	
	// Code generation of match method
	
	public void generateSGLRMethod_match(String indent, StringBuffer buf) {
	
		// Method signature
		buf.append(indent + "protected LexicalNode match(LexicalNode previous, " + 
			"Interval interval, String label, String value) {\n");
		
		// Method body
		for (int i = 0; i < getNumGrammar(); i++) {
			Grammar g = getGrammar(i);
			for (Object obj : g.nodeDecls()) {
				NodeDecl decl = (NodeDecl)obj;
				if (!decl.inBaseLibrary())
					decl.generateSGLRMethod_match(indent + indent, buf);
			}
		}
				
		// Method end
		buf.append(indent + indent + "return createWater(previous, interval, value);\n");
		buf.append(indent + "}\n\n");
	}

    // Declared in ParserCodeGen.jrag at line 188

	
	// Code generation of createWater method
	
	public void generateSGLRMethod_createWater(String indent, StringBuffer buf) {
		buf.append(indent + "protected LexicalNode createWater(LexicalNode previous, " + 
			"Interval interval, String value) {\n");
		buf.append(indent + indent + "return new Water(previous, interval, value);\n");
		buf.append(indent + "}\n\n");
	}

    // Declared in ParserCodeGen.jrag at line 197

	
	// Code generation of mergeNodes method
	
	public void generateSGLRMethod_mergeNodes(String indent, StringBuffer buf) {
		buf.append(indent + "protected void mergeNodes(SOF sof) {\n");
		buf.append(indent + indent + "mergeWater(sof);\n");
		buf.append(indent + "}\n\n");
	}

    // Declared in PreAnalysis.jrag at line 8


	public void prepForAnalysis() {
	
		// Manually add a grammar corresponding to the base library
		
		List childList = new List();
		
		// Base node: LexicalNode
		NodeDecl lexNode = new NodeDecl("LexicalNode", new Opt());
		lexNode.setInBaseLibrary(true);
		childList.add(lexNode);
		
		// Base attr: LexicalNode.value
		JavaAttrDecl valueAttr = new JavaAttrDecl(new NodeUse("LexicalNode"), 
			"value", "String", new JavaBlock(""));
		childList.add(valueAttr);
	
		// Base node: Island
		AbstractIslandDecl islandNode = new AbstractIslandDecl("Island", new Opt(new NodeUse("LexicalNode")));
		islandNode.setInBaseLibrary(true);
		childList.add(islandNode);
			
		// Base attr: Island.hasBridge
		JavaAttrDecl hasBridgeAttr = new JavaAttrDecl(new NodeUse("Island"), 
			"hasBridge", "boolean",  new JavaBlock(""));
		childList.add(hasBridgeAttr);
		
		// Base node: Reef
		AbstractReefDecl reefNode = new AbstractReefDecl("Reef", new Opt(new NodeUse("LexicalNode")));
		reefNode.setInBaseLibrary(true);
		childList.add(reefNode);
		
		Grammar grammar = new Grammar("base", childList);
		this.addGrammar(grammar);
	}

    // Declared in bridgit.ast at line 3
    // Declared in bridgit.ast line 10

    public Program() {
        super();

        setChild(new List(), 0);
        is$Final(true);

    }

    // Declared in bridgit.ast at line 12


    // Declared in bridgit.ast line 10
    public Program(List<Grammar> p0) {
        setChild(p0, 0);
        is$Final(true);
    }

    // Declared in bridgit.ast at line 17


  protected int numChildren() {
    return 1;
  }

    // Declared in bridgit.ast at line 20

  public boolean mayHaveRewrite() { return false; }

    // Declared in bridgit.ast at line 2
    // Declared in bridgit.ast line 10
    public void setGrammarList(List<Grammar> list) {
        setChild(list, 0);
    }

    // Declared in bridgit.ast at line 6


    private int getNumGrammar = 0;

    // Declared in bridgit.ast at line 7

    public int getNumGrammar() {
        return getGrammarList().getNumChild();
    }

    // Declared in bridgit.ast at line 11


     @SuppressWarnings({"unchecked", "cast"})  public Grammar getGrammar(int i) {
        return (Grammar)getGrammarList().getChild(i);
    }

    // Declared in bridgit.ast at line 15


    public void addGrammar(Grammar node) {
        List<Grammar> list = getGrammarList();
        list.addChild(node);
    }

    // Declared in bridgit.ast at line 20


    public void setGrammar(Grammar node, int i) {
        List<Grammar> list = getGrammarList();
        list.setChild(node, i);
    }

    // Declared in bridgit.ast at line 24

    public List<Grammar> getGrammars() {
        return getGrammarList();
    }

    // Declared in bridgit.ast at line 27

    public List<Grammar> getGrammarsNoTransform() {
        return getGrammarListNoTransform();
    }

    // Declared in bridgit.ast at line 31


     @SuppressWarnings({"unchecked", "cast"})  public List<Grammar> getGrammarList() {
        return (List<Grammar>)getChild(0);
    }

    // Declared in bridgit.ast at line 35


     @SuppressWarnings({"unchecked", "cast"})  public List<Grammar> getGrammarListNoTransform() {
        return (List<Grammar>)getChildNoTransform(0);
    }

    // Declared in TypeCodeGen.jrag at line 19
    private boolean collect_contributors_Grammar_nodeDecls = false;
    protected void collect_contributors_Grammar_nodeDecls() {
        if(collect_contributors_Grammar_nodeDecls) return;
        super.collect_contributors_Grammar_nodeDecls();
        collect_contributors_Grammar_nodeDecls = true;
    }



    // Declared in TypeCodeGen.jrag at line 25
    private boolean collect_contributors_Grammar_ignoreDecls = false;
    protected void collect_contributors_Grammar_ignoreDecls() {
        if(collect_contributors_Grammar_ignoreDecls) return;
        super.collect_contributors_Grammar_ignoreDecls();
        collect_contributors_Grammar_ignoreDecls = true;
    }



    // Declared in TypeCodeGen.jrag at line 22
    private boolean collect_contributors_NodeDecl_attrDecls = false;
    protected void collect_contributors_NodeDecl_attrDecls() {
        if(collect_contributors_NodeDecl_attrDecls) return;
        super.collect_contributors_NodeDecl_attrDecls();
        collect_contributors_NodeDecl_attrDecls = true;
    }



    // Declared in NameAnalysis.jrag at line 230
 @SuppressWarnings({"unchecked", "cast"})     public NodeDecl lookupNode(String name) {
        NodeDecl lookupNode_String_value = lookupNode_compute(name);
        return lookupNode_String_value;
    }

    private NodeDecl lookupNode_compute(String name) {
		for (int i = 0; i < getNumGrammar(); i++) {
			NodeDecl decl = getGrammar(i).lookupNodeDecl(name);
			if (decl != null)
				return decl;
		}
		
		/*
		if (name.equals("Island")) {
			return NODE_DECL_Island;
		}
		*/
		return null;
	}

    // Declared in NameAnalysis.jrag at line 282
 @SuppressWarnings({"unchecked", "cast"})     public BridgeDecl lookupBridge(String name) {
        BridgeDecl lookupBridge_String_value = lookupBridge_compute(name);
        return lookupBridge_String_value;
    }

    private BridgeDecl lookupBridge_compute(String name) {
		for (int i = 0; i < getNumGrammar(); i++) {
			BridgeDecl decl = getGrammar(i).lookupBridgeDecl(name);
			if (decl != null)
				return decl;
		}
		return null;
	}

    // Declared in NameAnalysis.jrag at line 84
    public RecoverDecl Define_RecoverDecl_lookupRecovery(ASTNode caller, ASTNode child, String name) {
        if(caller == getGrammarListNoTransform()) { 
   int index = caller.getIndexOfChild(child);
{
		for (int k = 0; k < getNumGrammar(); k++) {
			Grammar g = getGrammar(k);
			for (int i = 0; i < g.getNumElement(); i++) {
				Element e = g.getElement(i);
				if (e.isRecoverDecl()) {
					RecoverDecl recovery = (RecoverDecl)e;
					if (recovery.getNodeUse().getName().equals(name)) {
						return recovery;
					}
				}
			}
		}
		return null;
	}
}
        return getParent().Define_RecoverDecl_lookupRecovery(this, caller, name);
    }

public ASTNode rewriteTo() {
    return super.rewriteTo();
}

}
